{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 캐싱(Caching)\n",
    "\n",
    "LangChain은 LLM을 위한 선택적 캐싱 레이어를 제공합니다.\n",
    "\n",
    "이는 두 가지 이유로 유용합니다.\n",
    "\n",
    "- 동일한 완료를 여러 번 요청하는 경우 LLM 공급자에 대한 **API 호출 횟수를 줄여 비용을 절감**할 수 있습니다.\n",
    "- LLM 제공업체에 대한 **API 호출 횟수를 줄여 애플리케이션의 속도를 높일 수** 있습니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# API KEY를 환경변수로 관리하기 위한 설정 파일\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "# API KEY 정보로드\n",
    "load_dotenv()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# LangSmith 추적을 설정합니다. https://smith.langchain.com\n",
    "# !pip install langchain-teddynote\n",
    "from langchain_teddynote import logging\n",
    "\n",
    "# 프로젝트 이름을 입력합니다.\n",
    "logging.langsmith(\"CH04-Models\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "모델과 프롬프트를 생성합니다\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_core.prompts import PromptTemplate\n",
    "\n",
    "# 모델을 생성합니다.\n",
    "llm = ChatOpenAI(model_name=\"gpt-3.5-turbo\")\n",
    "\n",
    "# 프롬프트를 생성합니다.\n",
    "prompt = PromptTemplate.from_template(\"{country} 에 대해서 200자 내외로 요약해줘\")\n",
    "\n",
    "# 체인을 생성합니다.\n",
    "chain = prompt | llm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time \n",
    "response = chain.invoke({\"country\": \"한국\"})\n",
    "print(response.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## InMemoryCache\n",
    "\n",
    "인메모리 캐시를 사용하여 동일 질문에 대한 답변을 저장하고, 캐시에 저장된 답변을 반환합니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "from langchain.globals import set_llm_cache\n",
    "from langchain.cache import InMemoryCache\n",
    "\n",
    "# 인메모리 캐시를 사용합니다.\n",
    "set_llm_cache(InMemoryCache())\n",
    "\n",
    "# 체인을 실행합니다.\n",
    "response = chain.invoke({\"country\": \"한국\"})\n",
    "print(response.content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "# 체인을 실행합니다.\n",
    "response = chain.invoke({\"country\": \"한국\"})\n",
    "print(response.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## SQLite Cache\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.cache import SQLiteCache\n",
    "from langchain_core.globals import set_llm_cache\n",
    "import os\n",
    "\n",
    "# 캐시 디렉토리를 생성합니다.\n",
    "if not os.path.exists(\"cache\"):\n",
    "    os.makedirs(\"cache\")\n",
    "\n",
    "# SQLiteCache를 사용합니다.\n",
    "set_llm_cache(SQLiteCache(database_path=\"cache/llm_cache.db\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time \n",
    "# 체인을 실행합니다.\n",
    "response = chain.invoke({\"country\": \"한국\"})\n",
    "print(response.content)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py-test",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
